package org.lcx.pipeline.impl;

import java.text.MessageFormat;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import org.lcx.pipeline.Processor;
import org.lcx.pipeline.bean.PipelineExeption;
import org.lcx.pipeline.bean.PipelineResult;
import org.lcx.pipeline.bean.Transition;

/**
 * pipeline linke，定义chain中的一个processor节点<br>
 * 在此类中真正调用某一个processor,并控制单个processor的事务
 */
public class PipelineLink {
	public final Log log = LogFactory.getLog(this.getClass());

	// pipeline link id
	private String id;
	// pipeline link name
	private String name;
	// pipeline link 事务描述
	private String transaction;
	// pipelineLinke关联的processor
	private Processor processor;
	// pipelineLinke对应的下一个节点的信息<br>
	// key：返回的值, value: 下一个节点的信息
	private ManagedMap<Integer, Transition> transitions;
	// 事务对象
	public PlatformTransactionManager transactionManager;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTransaction() {
		return transaction;
	}

	public void setTransaction(String transaction) {
		this.transaction = transaction;
	}

	public Processor getProcessor() {
		return processor;
	}

	public void setProcessor(Processor processor) {
		this.processor = processor;
	}

	public ManagedMap<Integer, Transition> getTransitions() {
		return transitions;
	}

	public void setTransitions(ManagedMap<Integer, Transition> transitions) {
		this.transitions = transitions;
	}

	public PlatformTransactionManager getTransactionManager() {
		return transactionManager;
	}

	public void setTransactionManager(PlatformTransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	/**
	 * 执行link对应的processor业务方法
	 * 
	 * @param result
	 * @param pParam
	 * @return
	 */
	public int runProcess(PipelineResult result, Object pParam) throws PipelineExeption {
		int ret = 0;

		// 事务处理
		DefaultTransactionDefinition definition = new DefaultTransactionDefinition(PipelineConfig.getTransactionMode(this.transaction));
		TransactionStatus status = transactionManager.getTransaction(definition);
		boolean rollback = true;
		try {
			ret = this.processor.runProcess(pParam, result);
			rollback = false;
		} catch (PipelineExeption e) {
			String msgFormat = "pipelineLink(name:{0},processor:{1})处理错误";
			log.error(MessageFormat.format(msgFormat, this.name, this.processor), e);
			throw e;
		} catch (Exception e) {
			String msgFormat = "pipelineLink(name:{0},processor:{1})处理错误";
			log.error(MessageFormat.format(msgFormat, this.name, this.processor), e);
			throw new PipelineExeption(e);
		} finally{
			if (rollback) {
				this.transactionManager.rollback(status);
			} else {
				this.transactionManager.commit(status);
			}
		}
		return ret;
	}

	/**
	 * 获取当前节点的可能存在的下一个节点的数量
	 * 
	 * @return
	 */
	public int getNextLinkCount() {
		if (transitions == null) {
			return 0;
		}
		return transitions.size();
	}

	/**
	 * 根据返回的信息，获取对应的下一个节点信息
	 * 
	 * @param ret
	 * @return
	 */
	public String getNextLink(int ret) {
		Transition transition = transitions.get(ret);
		if(null != transition){
			return transition.getLink();
		}
		return null;
	}

	@Override
	public String toString() {
		return "PipelineLink{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", transaction='" + transaction + '\''
				+ ", processor=" + processor + ", transitions=" + transitions + '}';
	}
}
